package com.controller;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.dequeue.DeQueueList;
import com.domain.Aeropuerto;
import com.domain.Avion;
import com.domain.EmptyParkException;
import com.queue.PriorityQueueList;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.view.MainWindow;

public class MainWindowController {

	// Servicio que lanza 1...* ejecutables en distintos hilos de ejecucion
	// simultaneamente.
	private static ExecutorService backgroundExec;

	private static MainWindowController instancia = null;
	private static Aeropuerto MeridaAirport;
	private static DeQueueList parkingLane;
	private static PriorityQueueList enEspera;
	
	private static XStream xstream;

	// Se asignan los atributos estaticamente
	static {
		backgroundExec = Executors.newCachedThreadPool();
		xstream = new XStream(new DomDriver());
	}

	public static final MainWindowController getInstance() {
		if (instancia == null) {
			instancia = new MainWindowController();
		}
		return instancia;
	}

	private MainWindowController() {
		// TODO Auto-generated constructor stub
		MeridaAirport = new Aeropuerto();
		xstream.alias("estacionamiento", DeQueueList.class);
		randomizeInit();
		initAirport();
	}

	private static void randomizeInit() {

		
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());
		MeridaAirport.llegada(new Avion());

	}

	public static void initAirport() {

		MainWindow.getInstance();
		populateTaxiLane();
		/*
		 * // Agregamos las avionetas // aeropuerto.llegada(uno);
		 * aeropuerto.llegada(dos); aeropuerto.llegada(tres);
		 * aeropuerto.llegada(cuatro); aeropuerto.llegada(cinco);
		 * aeropuerto.llegada(seis); aeropuerto.llegada(siete);
		 * aeropuerto.llegada(ocho); aeropuerto.llegada(nueve);
		 * aeropuerto.llegada(diez); aeropuerto.llegada(once);
		 * aeropuerto.llegada(doce); aeropuerto.llegada(trece);
		 * aeropuerto.llegada(catorce); aeropuerto.llegada(quince);
		 * aeropuerto.llegada(diezyseis);
		 */

	}

	public static void populateTaxiLane() {

		// Crea un XML del estacionamiento del Aeropuerto, y el estacionamiento
		// grafico lo instancia.
		parkingLane = (DeQueueList) xstream.fromXML(xstream.toXML(MeridaAirport
				.getEstacionamiento()));

		// Instancia la ventana, y elimina todos los aviones de la pista
		// TaxiLane
		MainWindow ventana = MainWindow.getInstance();
		ventana.wipeTaxiLane();

		Avion avionEnPista;

		while (!parkingLane.isEmpty()) {
			avionEnPista = (Avion) MainWindowController.parkingLane
					.removeFromLast();
			ventana.drawTaxiLane(avionEnPista.getNumMatricula(),
					avionEnPista.getNumPasajeros(),
					avionEnPista.getCantidadFuel());
		}

	}
	
	public static void populateHoldingPattern(){
		
		enEspera = (PriorityQueueList) xstream.fromXML(xstream.toXML(MeridaAirport
				.getEnEspera()));
		
		MainWindow ventana = MainWindow.getInstance();
		ventana.wipeHoldingPattern();
		
		Avion avionEnPista;

		while (!enEspera.isEmpty()) {
			avionEnPista = (Avion) MainWindowController.enEspera.removeMinElement();
			ventana.drawSky(avionEnPista.getNumMatricula(),
					avionEnPista.getNumPasajeros(),
					avionEnPista.getCantidadFuel());
		}
		
	}
	

	public static void arrive(String matricula, int pasajeros, int fuel) {

		if(MeridaAirport.llegada(new Avion(matricula, fuel, pasajeros)) == MeridaAirport.TAXI_LANE_IS_FULL){
			populateHoldingPattern();
			populateTaxiLane();
		}else{
			populateTaxiLane();
		}
		
	}

	public static boolean departure() {

		try {
			if(MeridaAirport.salida()){
				populateHoldingPattern();
			}
			populateTaxiLane();
			
			return true;
		} catch (EmptyParkException e) {
			return false;
		}
	}

}
